﻿#ifndef __FileSystem_H__
#define __FileSystem_H__

#include "kernel/OgreArchive.h"
#include "kernel/OgreArchiveFactory.h"
#include "kernel/OgreStringvector.h"
#include "kernel/threading/OgreThreadHeaders.h"
#include "observer_ptr.h"

namespace FD
{
	namespace Kernel
	{
		/**** Specialisation of the Archive class to allow reading of files from
		filesystem folders / directories.
		****/
		class FD_Kernel_Export FileSystemArchive : public FD::Kernel::Archive
		{
		protected:
			/**** Utility method to retrieve all files in a directory matching pattern.
			@param pattern File pattern
			@param recursive Whether to cascade down directories
			@param dirs Set to true if you want the directories to be listed
			instead of files
			@param simpleList Populated if retrieving a simple list
			@param detailList Populated if retrieving a detailed list
			@param currentDir The current directory relative to the base of the
			archive, for file naming
			****/
			void findFiles(const String &pattern, bool recursive, bool dirs,
				FD::Kernel::StringVector *simpleList, FileInfoList *detailList) const;
			OGRE_AUTO_MUTEX;
		public:
			/*FileSystemArchive(const String &name, const String &archType );*/
			 FileSystemArchive(const String& name, const String& archType, bool readOnly );

			~FileSystemArchive();
			//// @copydoc Archive::isCaseSensitive
			bool isCaseSensitive() const;
			//// @copydoc Archive::load
			void load();
			//// @copydoc Archive::unload
			void unload();
			//// @copydoc Archive::open
			FD::Kernel::DataStreamPtr open(const String &filename, bool readOnly = true) const;
			//// @copydoc Archive::create
			FD::Kernel::DataStreamPtr create(const String &filename) const;
			//// @copydoc Archive::delete
			void remove(const String &filename) const;
			//// @copydoc Archive::list
			virtual void list(FD::Kernel::StringVector& result, bool recursive = true, bool dirs = false);
			//// @copydoc Archive::listFileInfo
			virtual void listFileInfo(FD::Kernel::FileInfoList& result, bool recursive = true, bool dirs = false );
			//// @copydoc Archive::find
			virtual void find(FD::Kernel::StringVector& result, const String &pattern, bool recursive = true, bool dirs = false );
			//// @copydoc Archive::findFileInfo
			virtual void findFileInfo(FD::Kernel::FileInfoList& result, const String &pattern, bool recursive = true, bool dirs = false ) const;

			//// @copydoc Archive::exists
			bool exists(const String &filename);

			//// Set whether filesystem enumeration will include hidden files or not.
			//// This should be called prior to declaring and/or initializing filesystem
			//// resource locations. The default is true (ignore hidden files).
			static void setIgnoreHidden(bool ignore)
			{
				ms_IgnoreHidden = ignore;
			}
			//// Get whether hidden files are ignored during filesystem enumeration.
			static bool getIgnoreHidden()
			{
				return ms_IgnoreHidden;
			}
			static bool ms_IgnoreHidden;
			////public:
			//// @copydoc Archive::getModifiedTime
			INT64 getModifiedTime(const String &filename);
		};
		/**** Specialisation of FD::Kernel::ArchiveFactory for FileSystem files. ****/
		class FD_Kernel_Export CFileSystemArchiveFactory : public FD::Kernel::ArchiveFactory
		{
		public:
			CFileSystemArchiveFactory() {}
			virtual ~CFileSystemArchiveFactory() {}
			//// @copydoc FactoryObj::getType
			String getType() const;
			//// @copydoc FactoryObj::createInstance
			FD::Kernel::Archive *createInstance( const String& name, bool readOnly ) 
			{
				return OGRE_NEW FileSystemArchive(name, "FileSystem", readOnly);
			}
			//// @copydoc FactoryObj::destroyInstance
			void destroyInstance( FD::Kernel::Archive *arch)
			{
				delete arch;
			}
		};
	}
}

#endif

